﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using KAImage.Algorithms;

namespace IPCPhotoEditor
{
    public partial class HistogramControl : UserControl
    {
        /// <summary>
        /// 整个图层的宽度
        /// </summary>
        private readonly int W = 256;

        /// <summary>
        /// 整个图层的高度
        /// </summary>
        private readonly int H = 120;

        /// <summary>
        /// 直方图统计数据
        /// </summary>
        private int[] _data = null;
        public int[] Data
        {
            get { return _data; }
            set 
            { 
                _data = value;             
            }
        }

        private int _nMedianPixel = 1; 

        private Color _bgColor = Color.FromArgb(255, 69, 69, 69);

        private Bitmap _bkgImage = null;

        private Color _lineColor = Color.Red;
        public Color HistogramColor
        {
             get { return _lineColor; }
             set { _lineColor = value; }
        }

        public HistogramControl()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.UpdateStyles();
        }

        private void DisposeOldImage()
        {
            this.BackgroundImage = null;
            if (_bkgImage != null)
            {
                _bkgImage.Dispose();
                _bkgImage = null;
            }
        }

        private void CreatHistogram()
        {
            try
            {
                _bkgImage = new Bitmap(W, H, PixelFormat.Format32bppArgb);
                using (Graphics g = Graphics.FromImage(_bkgImage))
                {
                    g.Clear(_bgColor);
                    if (_data == null || _data.Length != 256)
                    {
                        return;
                    }
                    using (Pen linePen = new Pen(_lineColor, 1))
                    {
                        //绘制直方图
                        double temp = 0;
                        for (int i = 0; i < _data.Length; i++)
                        {
                            temp = (double)H * _data[i] / _nMedianPixel;
                            g.DrawLine(linePen, i + 1, H, i + 1, H - (int)temp);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void CreatHistogram(int[] dR, int[] dG, int[] dB)
        {
            try
            {
                _bkgImage = new Bitmap(W, H, PixelFormat.Format32bppArgb);
                using (Graphics g = Graphics.FromImage(_bkgImage))
                {
                    g.Clear(_bgColor);                  
                    Color redCol = Color.FromArgb(128, 255, 0, 0);
                    using (Pen linePen = new Pen(redCol, 1))
                    {
                        //绘制直方图R
                        double temp = 0;
                        for (int i = 0; i < dR.Length; i++)
                        {
                            temp = (double)H * dR[i] / _nMedianPixel;
                            g.DrawLine(linePen, i + 1, H, i + 1, H - (int)temp);
                        }

                        //绘制直方图G
                        linePen.Color = Color.FromArgb(128, 0, 255, 0);
                        for (int i = 0; i < dG.Length; i++)
                        {
                            temp = (double)H * dG[i] / _nMedianPixel;
                            g.DrawLine(linePen, i + 1, H, i + 1, H - (int)temp);
                        }

                        //绘制直方图B
                        linePen.Color = Color.FromArgb(128, 0, 0, 255);
                        temp = 0;
                        for (int i = 0; i < dB.Length; i++)
                        {
                            temp = (double)H * dB[i] / _nMedianPixel;
                            g.DrawLine(linePen, i+1, H, i+1, H - (int)temp);
                        }
                    }                                     
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public void UpdateHistogram(ImageHistograms histograms, ColorChannel channel)
        {
            if (histograms.nChannelMedianPixel == 0)
            {
                throw new Exception("直方图中位数计算错误");
            }
            switch (channel)
            {
                case ColorChannel.R:
                    _data = histograms.hR;
                    _nMedianPixel = histograms.nChannelMedianPixel;     
                    break;
                case ColorChannel.G:
                    _data = histograms.hG;
                    _nMedianPixel = histograms.nChannelMedianPixel;     
                    break;
                case ColorChannel.B:
                    _data = histograms.hB;
                    _nMedianPixel = histograms.nChannelMedianPixel;     
                    break;
                case ColorChannel.RGB:
                    _data = histograms.hRGB;
                    _nMedianPixel = histograms.nMedianPixel;     
                    break;
                default:
                    return;
            }             
            DisposeOldImage();
            CreatHistogram();
            this.BackgroundImage = _bkgImage;
        }

        public void UpdateHistogram(ImageHistograms histograms)
        {        
            _nMedianPixel = histograms.nChannelMedianPixel;
            DisposeOldImage();
            CreatHistogram(histograms.hR, histograms.hG, histograms.hB);
            this.BackgroundImage = _bkgImage;
        }

        private void HistogramControl_Load(object sender, EventArgs e)
        {
            CreatHistogram();
            this.BackgroundImage = _bkgImage;
        }

        public void ClearHistogram()
        {
            DisposeOldImage();
        }
    }
}
